package com.atguigui.webfluxdemo2;

import com.atguigui.webfluxdemo2.handler.UserHandler;
import com.atguigui.webfluxdemo2.service.UserService;
import com.atguigui.webfluxdemo2.service.impl.UserServiceImpl;
import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.netty.http.server.HttpServer;


import java.io.IOException;

import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RequestPredicates.accept;
import static org.springframework.web.reactive.function.server.RouterFunctions.toHttpHandler;

/**
 * Spring WebFlux(基于函数式编程模型)
 *      (1) 在使用函数式编程模型操作的时候,需要自己初始化服务器。
 *      (2) 基于函数式编程模型时候，有两个核心接口: RouterFunction(实现路由功能,
 *      请求转发给对应的handler)和HandlerFunction(处理请求生成响应的函数)。
 *      核心任务定义两个函数式接口的实现并且启动需要的服务器。
 *      (3) SpringWebFlux请求和响应不再是ServletRequest和ServletResponse,
 *      而是ServerRequest和ServerResponse.
 *
 */
public class Server {


    //4.最终启动调用
    public static void main(String[] args) throws IOException {
        Server server = new Server();
        server.createReactorServer();
        System.out.println("enter to exit");
        System.in.read();
    }


    //1.创建Router路由
    public RouterFunction<ServerResponse> routingFunction() {
        //创建handler对象
        UserService userService = new UserServiceImpl();
        UserHandler handler = new UserHandler(userService);
        //设置路由
        return RouterFunctions.route(
                GET("/users/{id}").and(accept(APPLICATION_JSON)),
                handler::getUserById
        ).andRoute(GET("/users").and(accept(APPLICATION_JSON)), handler::getAllUsers);
    }


    //3.创建服务器完成适配
    public void createReactorServer() {
        //路由和handler适配
        RouterFunction<ServerResponse> routerFunction = routingFunction();
        HttpHandler httpHandler = toHttpHandler(routerFunction);
        ReactorHttpHandlerAdapter reactorHttpHandlerAdapter = new ReactorHttpHandlerAdapter(httpHandler);


        //创建服务器
        HttpServer httpServer = HttpServer.create();
        httpServer.handle(reactorHttpHandlerAdapter).bindNow();


    }


}
